package smartcase.common.util;

import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

public class NetUtils {
  public static String getLocalIP() {
    List<Inet4Address> addresses = getLocalIp4AddressFromNetworkInterface();
    return getLocalIp4AddressFromNetworkInterface().stream()
        .filter(t -> !"127.0.0.1".equals(t.getHostAddress()))
        .map(Inet4Address::getHostAddress)
        .findFirst()
        .orElse("no ip");
  }

  public static List<Inet4Address> getLocalIp4AddressFromNetworkInterface() {
    try {
      List<Inet4Address> addresses = new ArrayList<>(1);
      Enumeration e = NetworkInterface.getNetworkInterfaces();
      if (e == null) {
        return addresses;
      }
      while (e.hasMoreElements()) {
        NetworkInterface n = (NetworkInterface) e.nextElement();
        if (!isValidInterface(n)) {
          continue;
        }
        Enumeration ee = n.getInetAddresses();
        while (ee.hasMoreElements()) {
          InetAddress i = (InetAddress) ee.nextElement();
          if (isValidAddress(i)) {
            addresses.add((Inet4Address) i);
          }
        }
      }
      return addresses;
    } catch (Exception e) {
      e.printStackTrace();
      return new ArrayList<>();
    }
  }

  private static boolean isValidInterface(NetworkInterface ni) throws SocketException {
    return !ni.isLoopback()
        && !ni.isPointToPoint()
        && ni.isUp()
        && !ni.isVirtual()
        && (ni.getName().startsWith("eth") || ni.getName().startsWith("ens"));
  }

  private static boolean isValidAddress(InetAddress address) {
    return address instanceof Inet4Address
        && address.isSiteLocalAddress()
        && !address.isLoopbackAddress();
  }
}
